#include "chatwindow.h"
#include "ui_chatwindow.h"
#include "tcpclient.h"
#include <QMessageBox>
#include <QJsonObject>
#include <QDateTime>
#include "clientdatabasemanager.h"
#include <QTextCursor> // 确保包含了这个头文件
#include <QTextTable>  // 确保包含了这个头文件
#include <QPixmap>
#include <QMessageBox>
#include <QJsonObject>
#include "friendrequestwidget.h"

ChatWindow::ChatWindow(TcpClient* client,QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::ChatWindow),m_currentChatFriendId(0),m_tcpClient(client),m_addFriendWidget(nullptr)
{
    ui->setupUi(this);

    //为新的朋友功能直接创建空间
    m_friendRequestWidget = new FriendRequestWidget();
    // 3. 初始时，这个窗口是不显示的
    m_friendRequestWidget->hide();

    // 连接列表项的点击信号
    connect(ui->friendsListWidget, &QListWidget::currentItemChanged,
            this, &ChatWindow::onCurrentFriendChanged);

    connect(ui->sendButton, &QRadioButton::clicked, this, &ChatWindow::on_sendButton_clicked);


    // 在这里连接 TcpClient 的信号，用于接收消息
    connect(m_tcpClient, &TcpClient::serverResponse, this, &ChatWindow::onServerResponse);

    //连接信号到chatwindow处理好友申请的请求

    // 将 FriendRequestWidget 发出的 "requestResponded" 信号，
    // 连接到我们刚刚在 ChatWindow 中声明的 "handleFriendRequestResponse" 槽函数上。
    connect(m_friendRequestWidget, &FriendRequestWidget::requestResponded,
            this, &ChatWindow::handleFriendRequestResponse);
}

ChatWindow::~ChatWindow()
{
    delete ui;
}

void ChatWindow::setCurrentUserInfo(const QJsonObject &userInfo)
{
    m_currentUserInfo = userInfo;
    // 可以将窗口标题设置为当前用户名
    this->setWindowTitle(QString("QTalk - %1").arg(userInfo["username"].toString()));
}

void ChatWindow::setFriendsList(const QJsonArray &friends)
{
    // 清空旧的好友列表
    ui->friendsListWidget->clear(); // 假设你的 QListWidget objectName 是 friendsListWidget

    for (const QJsonValue& value : friends)
    {
        QJsonObject friendObj = value.toObject();
        QString username = friendObj["username"].toString();
        int userId = friendObj["user_id"].toInt();
        QString status = friendObj["status"].toString();

        // 创建一个 QListWidgetItem 来显示
        QListWidgetItem* item = new QListWidgetItem(username);



        // --- 关键修改：根据 status 设置初始的图标和颜色 ---
        if (status == "online") {
            item->setIcon(QIcon(":/show/green"));
            item->setForeground(Qt::black); // 或者你喜欢的主题亮色
            QPixmap test(":/show/green");
            if(test.isNull() == true)
            {
                qDebug() << "setFriendList::green加载图片失败";
            }
        }
        else
        { // "offline"
            item->setIcon(QIcon(":/show/red"));
            item->setForeground(Qt::gray);
            QPixmap test(":/show/red");
            if(test.isNull() == true)
            {
                qDebug() << "setFriendList::red加载图片失败";
            }
        }
        // --- 修改结束 ---

        // 使用 setData 将好友的 user_id 隐藏地存储在列表项中，以后会用到！
        item->setData(Qt::UserRole, userId);

        ui->friendsListWidget->addItem(item);
    }
}


void ChatWindow::onCurrentFriendChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
    Q_UNUSED(previous); // 我们用不到前一个选项

    if (!current) { // 如果没有选中项（比如列表为空）
        m_currentChatFriendId = 0;
        return;
    }

    // 从列表项中，取出我们之前用 setData 隐藏起来的好友ID
    m_currentChatFriendId = current->data(Qt::UserRole).toInt();


    // 1. 清空聊天记录区
    ui->chatHistoryTextBrowser->clear();
    ui->currentFriendLabel->setText(current->text()); // 假设你有一个 QLabel叫 currentFriendLabel

    // 2. 从数据库加载历史记录
    int myId = m_currentUserInfo["user_id"].toInt();
    QList<QJsonObject> history = ClientDatabaseManager::instance().loadChatHistory(myId, m_currentChatFriendId);

    // 3. 遍历并显示历史记录
    for (const QJsonObject& message : history) {
        int fromId = message["from_id"].toInt();
        QString content = message["content"].toString();
        bool isMe = (fromId == myId); // <--- 明确判断
        QString senderName;

        if (isMe) {
            senderName = m_currentUserInfo["username"].toString();
        } else {
            senderName = current->text(); // current 是 QListWidgetItem*
        }
        appendMessageToHistory(senderName, content, isMe); // <--- 使用新版调用
    }


    qDebug() << "Switched to chat with friend ID:" << m_currentChatFriendId;

    // (可选) 在这里可以从本地数据库加载与该好友的历史聊天记录
}


void ChatWindow::on_sendButton_clicked()
{
    // 1. 前端校验
    if (m_currentChatFriendId == 0) {
        QMessageBox::warning(this, "提示", "请先选择一个聊天好友！");
        return;
    }
    QString content = ui->messageLineEdit->toPlainText();
    if (content.isEmpty()) {
        return; // 不发送空消息
    }

    // 2. 构建 private_message JSON
    QJsonObject message;
    message["type"] = "private_message";
    message["from_id"] = m_currentUserInfo["user_id"].toInt();
    message["to_id"] = m_currentChatFriendId;
    message["content"] = content;
    message["timestamp"] = QDateTime::currentSecsSinceEpoch();

    // !! 新增：将自己发送的消息存入数据库 !!
    // ClientDatabaseManager::instance().saveMessage(message);

    // 3. 发送 JSON
    //    我们需要一个 TcpClient 的实例。最好的方法是让它成为一个全局单例
    //    或者从 LoginWindow 传递过来。我们先用一个简化的方式。
    //    (这里需要修改，让 ChatWindow 能访问到 TcpClient)

    // 假设我们有一个 m_tcpClient 成员
    m_tcpClient->sendJson(message);


    // 4. 在自己的聊天窗口显示已发送的消息
    // (可以创建一个辅助函数来显示消息)
    appendMessageToHistory("Me", content,true);

    // 5. 清空输入框
    ui->messageLineEdit->clear();

    return ;
}

// (可以创建一个辅助函数来格式化并显示消息)
void ChatWindow::appendMessageToHistory(const QString &senderName, const QString &content, bool isMe)
{
    // 1. 根据 isMe 参数选择发送者名字的颜色
    QString nameColor = isMe ? "green" : "blue";

    // 2. 将消息内容中的HTML特殊字符进行转义，并保留换行符
    QString escapedContent = content.toHtmlEscaped().replace("\n", "<br>");

    QString displayName = isMe ? "Me" : senderName;

    // 3. 构造简单的 HTML 字符串
    // <b ...>...</b>: 加粗的、带颜色的发送者名字
    //  : 一个空格
    QString html = QString("<b style='color:%1;'>%2</b>: %3")
                       .arg(nameColor, displayName, escapedContent);

    // 4. 追加到 QTextBrowser，它会自动渲染HTML
    ui->chatHistoryTextBrowser->append(html);

    // 5. (可选) 确保视图总是滚动到最新消息
    ui->chatHistoryTextBrowser->ensureCursorVisible();
}

void ChatWindow::onServerResponse(const QJsonObject &response)
{


    QString type = response["type"].toString();
    qDebug() << "进入了onServerResponse." << "type = " << type;


    if (type == "private_message")
    {
        ClientDatabaseManager::instance().saveMessage(response);

        int fromId = response["from_id"].toInt();
        int toId = response["to_id"].toInt();
        int myId = m_currentUserInfo["user_id"].toInt();

        if ((fromId == myId && toId == m_currentChatFriendId) ||
            (fromId == m_currentChatFriendId && toId == myId))
        {
            QString content = response["content"].toString();
            QString senderName;
            bool isMe = (fromId == myId); // <--- 明确判断是否是我自己
            if (isMe) {
                senderName = m_currentUserInfo["username"].toString(); // 直接用自己的名字
            } else {
                senderName = ui->friendsListWidget->currentItem()->text(); // 用当前选中的好友名字
            }

            appendMessageToHistory(senderName, content, isMe); // <--- 使用新版调用
        }
        else
        {
            // 如果不是当前聊天对象，可以给对应的列表项一个“未读”提示
            // (高级功能，后续实现)
            qDebug() << "Received a message from user" << fromId << "but not in current chat.";
        }
    }
    else if(type ==  "friend_status_update")
    {
        int userId = response["user_id"].toInt();
        QString status = response["status"].toString();
        // QString username = response["username"].toString(); // 暂时用不到 username
        qDebug() << "将要更新好友列表状态";
        // 4. 调用我们之前设计的、专门用于更新UI的函数
        updateFriendStatus(userId, status);
    }
    else if (type == "add_friend_notification")
    {
        qDebug() << "[ChatWindow] Received a new friend request.";
        // 直接把整个 JSON 对象委托给 FriendRequestWidget 去处理
        m_friendRequestWidget->addRequest(response);

        // (进阶) 在这里可以更新 "新的朋友" 按钮的角标，提示有新消息
        // ui->newFriendButton->setText("新的朋友(1)");
    }
    else if(type == "add_friend_result")
    {
        qDebug() << "[ChatWindow] Handling add_friend_result...";
        handleFriendRequestResult(response); // 把逻辑委托给一个新函数处理
    }
    else
    {
        qDebug() << "chatwindow::onServerResponse不知道的类型";
    }
    return ;
}


void ChatWindow::updateFriendStatus(int id,QString status)
{
    // 遍历好友列表 (ui->friendsListWidget)
    for (int i = 0; i < ui->friendsListWidget->count(); ++i) {
        QListWidgetItem* item = ui->friendsListWidget->item(i);

        qDebug() << "  -> Checking item at index" << i << "Text:" << item->text() << "Stored ID:" << item->data(Qt::UserRole).toInt();

        // 通过我们之前存在 UserRole 里的数据来匹配用户ID
        if (item->data(Qt::UserRole).toInt() == id) {

            qDebug() << "  ==> MATCH FOUND! Updating UI for" << item->text();

            // 找到了对应的列表项，现在根据状态更新它的外观
            if (status == "online") {
                item->setIcon(QIcon(":/show/green"));
                item->setForeground(Qt::black); // 或者你喜欢的主题亮色
            } else { // "offline"
                item->setIcon(QIcon(":/show/red"));
                item->setForeground(Qt::gray);
            }

            // 找到并更新后，就可以提前结束函数了
            return;
        }
    }
    return ;
}

void ChatWindow::on_addFriend_pushButton_clicked()
{
    //采用懒汉模式。只申请一次空间
    if(this->m_addFriendWidget == nullptr)
    {
        this->m_addFriendWidget = new AddFriendWidget();
        // 如果希望窗口关闭时自动销毁，可以设置一个属性
        // m_addFriendWidget->setAttribute(Qt::WA_DeleteOnClose);

        //在这里建立连接 ---
        connect(m_addFriendWidget, &AddFriendWidget::sendFriendRequest,
                this, &ChatWindow::onSendFriendRequest);

    }

    // 显示窗口
    m_addFriendWidget->show();
    // 如果想让它显示在最前面
    m_addFriendWidget->raise();
    m_addFriendWidget->activateWindow();
    return ;
}

void ChatWindow::onSendFriendRequest(const QString &username, const QString &message)
{
    qDebug() << "[ChatWindow] Preparing to send friend request to:" << username;

    // 1. 构建我们协议中定义的 add_friend_request JSON 对象
    QJsonObject requestJson;
    requestJson["type"] = "add_friend_request";

    // "from_id" 应该是当前登录用户的ID
    requestJson["from_id"] = m_currentUserInfo["user_id"].toInt();

    requestJson["to_username"] = username;
    requestJson["message"] = message;

    // 2. 调用 TcpClient (或你的网络模块) 发送这个 JSON
    if (m_tcpClient)// 确保网络客户端实例存在
    {
        m_tcpClient->sendJson(requestJson); // 假设你的网络类有这样一个发送JSON的函数
    }

    return ;
}

void ChatWindow::handleFriendRequestResponse(int fromId, bool accepted)
{
    qDebug() << "[ChatWindow] Responding to friend request from" << fromId << "Accepted:" << accepted;

    // 1. 构建我们协议中定义的 add_friend_response JSON 对象
    QJsonObject responseJson;
    responseJson["type"] = "add_friend_response";
    responseJson["from_id"] = fromId; // 申请人的ID
    responseJson["to_id"] = m_currentUserInfo["user_id"].toInt(); // 我自己的ID
    responseJson["accepted"] = accepted;

    // 2. 调用 TcpClient 发送这个 JSON
    if (m_tcpClient)
    {
        m_tcpClient->sendJson(responseJson);
    }

    return ;
}

void ChatWindow::handleFriendRequestResult(const QJsonObject &resultJson)
{
    bool success = resultJson["success"].toBool();

    if (success)
    {
        // --- 添加好友成功的处理逻辑 ---
        int friendId = resultJson["friend_id"].toInt();
        QString friendUsername = resultJson["friend_username"].toString();

        // 1. 在好友列表 UI 中添加新好友
        QListWidgetItem* item = new QListWidgetItem(friendUsername);
        item->setData(Qt::UserRole, friendId);

        // 默认新加的好友一定是在线的
        // 所以我们先设置为在线状态
        item->setIcon(QIcon(":/show/green"));
        item->setForeground(Qt::black);

        ui->friendsListWidget->addItem(item);

        // 2. 弹窗提示用户
        QMessageBox::information(this, "操作成功", "添加好友 " + friendUsername + " 成功！");

    } else
    {
        // --- 添加好友失败的处理逻辑 ---
        QString reason;
        if (resultJson.contains("reason") && resultJson["reason"].isString()) {
            // 1. 如果 "reason" 键存在，并且它的值确实是个字符串
            reason = resultJson["reason"].toString();
        } else {
            // 2. 否则，使用我们自己指定的默认值
            reason = "未知错误";
        }
    }

    return ;
}

void ChatWindow::on_newFriendpushButton_clicked()
{
    m_friendRequestWidget->show();
    m_friendRequestWidget->raise();
    m_friendRequestWidget->activateWindow();
    return ;
}

